﻿using System;
using System.Collections.Generic;
using System.Text;

namespace AmorCanino.Common.Logger.AdvanceLogger
{
    public class AdvanceLogger
        : IAdvancedLog
    {
        public delegate void AsyncLog(Exception ex);
        public event AsyncLog OnError;

        public bool TryLog(Action func)
        {
            return TryLog(func, new FileLogger(), null);
        }

        public bool TryLog(Action func, ILogger logger)
        {
            return TryLog(func, logger, null);
        }

        public bool TryLog(Action func, ILogger logger, LogEntry logEntry)
        {
            try
            {
                func();
                return true;
            }
            catch (Exception ex)
            {
                logEntry = logEntry ?? new LogEntry();

                logEntry.Message += GetExceptionStack(ex);
                logger.LogDetail = this.LogDetail;
                logger.LogLevel = this.LogLevel;
                logger.WriteLog(logEntry);

                TriggerError(ex);

                return false;
            }
        }

        private void TriggerError(Exception ex)
        {
            var ev = OnError;
            if (ev != null)
                ev(ex);
        }

        private string GetExceptionStack(Exception ex)
        {
            string resultData = string.Empty;

            resultData += ex.InnerException != null 
                ? "\n" + GetExceptionStack(ex.InnerException)
                : ex.Message;

            if (LogDetail == LogDetails.Verbose)
                resultData += "\nStack: " + ex.StackTrace;

            return resultData;
        }

        public LogLevels LogLevel
        {
            get;
            set;
        }

        public LogDetails LogDetail
        {
            get;
            set;
        }
    }
}